package com.itzhouwei.commerce.thread.core.demo5;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * JDK 的线程池内部提供了两个关闭方法，shutdownNow 和 shuwdown 方法。
 * <p>
 * shutdownNow 方法的解释是：线程池拒接收新提交的任务，同时立马关闭线程池，线程池里的任务不再执行。
 * <p>
 * shutdown 方法的解释是：线程池拒接收新提交的任务，同时等待线程池里的任务执行完毕后关闭线程池。
 *
 * @description:线程池关闭案例
 * @author：zw，微信公共号：yingshengzw
 * @date: 2021/8/28
 * @Copyright：公众号：搬砖暗夜码农 | 博客：https://itzhouwei.com - 沉淀、学习、分享、成长，让自己和他人都能有所收获！
 *
 *
 *
 *
线程池关闭方式	worker ****线程的中断	正在执行任务如何处理	等待队列的任务如何处理
shutdown	会对所有处于空闲状态的 worker 线程触发 interrupt 操作。	继续执行	等待队列的任务会继续执行。
shutdownNow	会对所有忙碌或非忙碌状态的 worker 线程触发 interrupt 操作。
继续执行	将队列中没有执行的任务放入到一个 List 集合中，并且返回给调用线程
 */
public class ZwExecutorShutDownDemo {

    private static void shutDownTest() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.err.println("executorService  begin = " + executorService);
                    while (true) {

                    }
                } finally {
                    System.err.println("executorService = end " + executorService);
                }
            }
        });
        Thread.sleep(2000);
        executorService.shutdown();
        System.out.println("executorService = shutdown " + executorService);
    }

    private static void shutDownNow() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.err.println("executorService  begin = " + executorService);
                    while (true) {

                    }
                } finally {
                    System.err.println("executorService = end " + executorService);
                }
            }
        });
        Thread.sleep(3000);
        executorService.shutdown();
        System.err.println("executorService = shutdown " + executorService);
    }


    /****
     * 死锁四个条件
     * 互斥条件：一个资源每次只能被一个进程使用。
     * 请求与保持条件：一个进程因请求资源而阻塞时，对已获得的资源保持不放。
     * 不剥夺条件：进程已获得的资源，在末使用完之前，不能强行剥夺。
     * 循环等待条件：若干进程之间形成一种头尾相接的循环等待资源关系。
     * 所以，避免死锁最简单的方法就是阻止循环等待条件，将系统中所有的资源设置标志位、排序，规定所有的进程申请资源必须以一定的顺序（升序或降序）做操作来避免死锁
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        shutDownTest();
        System.out.println("******************** " );
        shutDownNow();
    }
}
